#include <ximera/system/library.hpp>
#include <ximera/assert.hpp>
#include <ximera/exception.hpp>

#if defined(XIMERA_LINUX)
#include <dlfcn.h>
#endif

namespace ximera { namespace system
{
    Library::Library(String const& fileName)
        : _handle(0)
    {
    #if defined(XIMERA_WIN32)
        _handle = ::LoadLibrary(fileName.c_str());
    #elif defined(XIMERA_LINUX)
        _handle = dlopen(filename.c_str(), RTLD_LAZY);
    #endif

        XIMERA_CHECK(_handle, XIMERA_THROW(InvalidParamException, L"Could not load library: " + fileName));

        _fileName = fileName;
    }

    Library::~Library()
    {
    #if defined(XIMERA_WIN32)
        if (_handle)
            ::FreeLibrary(_handle);
    #elif defined(XIMERA_LINUX)
        if (_handle)
            dlclose(_handle);
    #endif
    }

    String const& Library::fileName() const
    {
        return _fileName;
    }

    LibraryHandle Library::handle() const
    {
        return _handle;
    }

    LibraryFunctionAddr Library::loadFunction(char const* name)
    {
    #if defined(XIMERA_WIN32)
        return ::GetProcAddress(_handle, name);
    #elif defined(XIMERA_LINUX)
        return (LibraryFunctionAddr) dlsym(_handle, name);
    #endif
    }
}}